import json
from pathlib import Path

from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_LINE_SPACING
from docx.oxml.ns import qn
from docx.shared import Pt, Cm
from docx.shared import RGBColor


# 读取文档内容Json文件
def load_json(result_json_path):
    with open(result_json_path, encoding="utf-8") as txt:
        jsondict = json.load(txt)
    txt.close()
    return jsondict


# 将json数据转换为tuple
def parse_table_data(data):
    records = []
    for key, value in data.items():
        rows = []
        for col in value:
            rows.append(col)
        rows = tuple(rows)
        records.append(rows)
    records = tuple(records)
    return records


def generate_table(document, records):
    row_num = len(records)
    col_num = len(records[0])
    table = document.add_table(rows=1, cols=col_num)
    table.allow_autofit = True
    table.style = "Table Grid"
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    # 添加表格标题
    row = table.rows[0].cells
    for i in range(col_num):
        row[i].text = records[0][i]

    # 添加表格内容
    for j in range(1, row_num):
        row_cells = table.add_row().cells
        for k in range(col_num):
            row_cells[k].text = str(records[j][k])

    for col in table.columns:
        for cell in col.cells:
            cell.paragraphs[
                0
            ].paragraph_format.alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER


def set_heading_style(run, level):
    if level == 0:
        run.bold = True
        run.font.color.rgb = RGBColor(0, 0, 0)
        run.font.size = Pt(16)
        run.font.name = "黑体"
        run._element.rPr.rFonts.set(qn("w:eastAsia"), "黑体")
    elif level == 1:
        run.bold = False
        run.font.color.rgb = RGBColor(0, 0, 0)
        run.font.size = Pt(14)
        run.font.name = "黑体"
        run._element.rPr.rFonts.set(qn("w:eastAsia"), "黑体")
    elif level == 2:
        run.font.color.rgb = RGBColor(0, 0, 0)
        run.font.size = Pt(14)
        run.font.name = "仿宋_GB2312"
        run._element.rPr.rFonts.set(qn("w:eastAsia"), "仿宋_GB2312")


def set_title_style(run):
    run.bold = True
    run.font.color.rgb = RGBColor(0, 0, 0)
    run.font.size = Pt(12)
    run.font.name = "仿宋_GB2312"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "仿宋_GB2312")


def add_para(document, paragraph, bold):
    p = document.add_paragraph("           ")
    paragraph_format = p.paragraph_format
    paragraph_format.space_after = Pt(6)
    paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
    for run in paragraph:
        if "null" in run:
            pass
        else:
            run = p.add_run(run)
            if bold:
                run.bold = True
            run.font.size = Pt(14)
            run.font.name = "仿宋_GB2312"
            run._element.rPr.rFonts.set(qn("w:eastAsia"), "仿宋_GB2312")


def add_img(document, content, key, level_1_counter, img_counter):
    # 添加图
    image = document.add_paragraph("")
    image.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    run = image.add_run("")
    img = Path.cwd() / Path(content[key]["path"])
    run.add_picture(str(img), width=Cm(10))
    # 添加图序号
    title = document.add_paragraph("")
    title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    run = title.add_run(
        "图" + str(level_1_counter - 1) + "." + str(img_counter) + " "
    )
    set_title_style(run)
    # 添加图标题
    run = title.add_run(content[key]["title"])
    set_title_style(run)


def add_tbl(document, content, key, level_1_counter, tbl_counter, data_json_path):
    # 添加表序号
    title = document.add_paragraph("")
    run = title.add_run(
        "表" + str(level_1_counter - 1) + "." + str(tbl_counter) + " "
    )
    set_title_style(run)
    # 添加表标题
    run = title.add_run(content[key]["title"])
    set_title_style(run)
    # 添加表
    table_data = content[key]["data"]
    data_json = load_json(data_json_path)
    data = data_json[table_data]
    records = parse_table_data(data)
    generate_table(document, records)
    document.add_paragraph("")


def generate_content(document, result_json_path, data_json_path):
    json = load_json(result_json_path)
    level_0_counter = 0
    for level_0_key in json:
        level_0_content = json[level_0_key]
        level_0_number = ["一、", "二、"]
        heading = document.add_heading("", level=0)
        run = heading.add_run(level_0_number[level_0_counter])
        set_heading_style(run, level=0)
        run = heading.add_run(level_0_key)
        set_heading_style(run, level=0)
        level_0_counter = level_0_counter + 1
        level_1_counter = 1
        for level_1_key in level_0_content:
            level_1_content = level_0_content[level_1_key]
            heading = document.add_heading("", level=1)
            paragraph_format = heading.paragraph_format
            # paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
            paragraph_format.space_before = Pt(3)
            paragraph_format.space_after = Pt(6)
            run = heading.add_run(str(level_1_counter) + ". ")
            set_heading_style(run, level=1)
            run = heading.add_run(level_1_key)
            set_heading_style(run, level=1)
            level_1_counter = level_1_counter + 1
            level_2_counter = 1
            level_2_img_counter = 1
            level_2_tbl_counter = 1
            for level_2_key in level_1_content:
                level_2_content = level_1_content[level_2_key]
                if "para" in level_2_key:
                    paragraph = level_1_content[level_2_key]
                    add_para(document, paragraph, bold=False)
                elif "bold" in level_2_key:
                    paragraph = level_2_content[level_3_key]
                    add_para(document, paragraph, bold=True)
                elif "img" in level_2_key:
                    add_img(
                        document,
                        level_1_content,
                        level_2_key,
                        level_1_counter,
                        level_2_img_counter,
                    )
                    level_2_img_counter = level_2_img_counter + 1
                elif "tab" in level_2_key:
                    add_tbl(
                        document,
                        level_1_content,
                        level_2_key,
                        level_1_counter,
                        level_2_tbl_counter,
                        data_json_path,
                    )
                    level_2_tbl_counter = level_2_tbl_counter + 1
                else:
                    heading = document.add_heading("     ", level=2)
                    paragraph_format = heading.paragraph_format
                    # paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE
                    paragraph_format.space_before = Pt(3)
                    paragraph_format.space_after = Pt(6)
                    run = heading.add_run(
                        str(level_1_counter - 1)
                        + "."
                        + str(level_2_counter)
                        + " "
                    )
                    set_heading_style(run, level=2)
                    run = heading.add_run(level_2_key)
                    set_heading_style(run, level=2)
                    level_2_counter = level_2_counter + 1

                for level_3_key in level_2_content:
                    if "img" in level_3_key:
                        add_img(
                            document,
                            level_2_content,
                            level_3_key,
                            level_1_counter,
                            level_2_img_counter,
                        )
                        level_2_img_counter = level_2_img_counter + 1
                    elif "tab" in level_3_key:
                        add_tbl(
                            document,
                            level_2_content,
                            level_3_key,
                            level_1_counter,
                            level_2_tbl_counter,
                            data_json_path,
                        )
                        level_2_tbl_counter = level_2_tbl_counter + 1
                    elif "para" in level_3_key:
                        paragraph = level_2_content[level_3_key]
                        add_para(document, paragraph, bold=False)
                    elif "bold" in level_3_key:
                        paragraph = level_2_content[level_3_key]
                        add_para(document, paragraph, bold=True)
                    else:
                        pass
        # 添加level0分页符
        if level_0_counter < len(json):
            document.add_page_break()
    return document
